
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Web.SessionState;
using System.Text;
using ScrewTurn.Wiki.PluginFramework;
using System.Globalization;

namespace ScrewTurn.Wiki
{

	public partial class DefaultPage : BasePage 
    {

        private PageInfo pageInfo;
        private PageContent c;

        protected void Page_Load(object sender, EventArgs e) {

			// Setup the CookiePath for the JavaScript code that manages Breadcrumbs Trail (open/close) which needs cookies
			if(!Page.IsPostBack) {
				StringBuilder sb = new StringBuilder();
				sb.Append(@"<script type=""text/javascript"">" + "\n<!--\n");
				sb.Append("var __cookiePath = \"" + Settings.CookiePath + "\";\n");
				sb.Append("// -->\n</script>");
				lblCookiePath.Text = sb.ToString();
			}

			// If no Page is specified, load Default Page
            string page = Request["Page"]!= null ? Request["Page"] : Settings.DefaultPage;

            pageInfo = Pages.Instance.FindPage(page);

			// LoginCookie is present AND User has not performed login yet -> redirect to login page
			if(SessionFacade.LoginKey == null && HttpContext.Current.Request.Cookies[Settings.LoginCookieName] != null) {
				Response.Redirect("Login.aspx?Redirect=" + Tools.UrlEncode(page) + Settings.PageExtension);
				return;
			}

            if(pageInfo == null) {
				Response.Redirect("PageNotFound.aspx?Page=" + Tools.UrlEncode(page));
            }

            if(Request["Edit"] == "1") {
                Response.Redirect("Edit.aspx?Page=" + Tools.UrlEncode(pageInfo.Name));
            }
			if(Request["History"] == "1") {
				Response.Redirect("History.aspx?Page=" + Tools.UrlEncode(pageInfo.Name));
			}

            c = Content.GetPageContent(pageInfo, true);

            Page.Title = c.Title + " - " + Settings.WikiTitle;

			SessionFacade.Breadcrumbs.AddPage(pageInfo);
        }

        public void LoadPage()
        {
			bool code = Request["Code"] == "1", discuss = Request["Discuss"] == "1";

			// This is needed HERE to make Redirection work, because the Redirections list is popoluated when Pages are formatted
			string formattedContent = Content.GetFormattedPageContent(pageInfo, true);

			// Check Redirection
			PageInfo dest = Redirections.Instance.GetDestination(pageInfo);
			string redirection = "";
			if(dest != null) {
				if(Request["NoRedirect"] != "1") {
					Response.Redirect(dest.Name + Settings.PageExtension + "?From=" + pageInfo.Name);
				}
				else {
					// Write redirection Hint
					StringBuilder sb = new StringBuilder();
					sb.Append(@"<div id=""RedirectionDiv"">");
					sb.Append(Resources.Messages.ThisPageRedirectsTo);
					sb.Append(": ");
					sb.Append(@"<a href=""");
					sb.Append(Tools.UrlEncode(dest.Name));
					sb.Append(Settings.PageExtension);
					sb.Append("?From=");
					sb.Append(Tools.UrlEncode(pageInfo.Name));
					sb.Append(@""">");
					PageContent k = Content.GetPageContent(dest, true);
					sb.Append(k.Title);
					sb.Append("</a></div>");
					redirection = sb.ToString();
				}
			}

			Response.Write(@"<a id=""PageTop""></a>");
			Response.Write(@"<div id=""PageHeaderDiv"">");
			Response.Write(@"<div id=""EditHistoryLinkDiv"">");
			if(!code && !discuss) {
				// Discuss
				Response.Write(@"<a id=""DiscussLink"" href=""");
				Response.Write(Tools.UrlEncode(pageInfo.Name));
				Response.Write(Settings.PageExtension);
				Response.Write(@"?Discuss=1&amp;NoRedirect=1"">");
				Response.Write(Resources.Messages.Discuss);
				int msg = Pages.Instance.GetMessageCount(pageInfo);
				Response.Write(" (");
				Response.Write(msg.ToString());
				Response.Write(")</a>");

				// Add "Edit this Page" or "View Page Code" button
				if(SessionFacade.LoginKey == null) {
					// Not logged-in
					if((pageInfo.Status == PageStatus.Public || Settings.PublicAccess) && pageInfo.Status != PageStatus.Locked && !pageInfo.Provider.ReadOnly) PrintEditPage();
					else PrintViewCode();
				}
				else {
					// Logged-in
					if(pageInfo.Status == PageStatus.Locked && !SessionFacade.Admin) PrintViewCode();
					else if(!pageInfo.Provider.ReadOnly) PrintEditPage();
					else PrintViewCode();
				}
			}
			else {
				if(discuss && !pageInfo.Provider.ReadOnly) {
					Response.Write(@"<a id=""PostReplyLink"" href=""Post.aspx?Page=" + Tools.UrlEncode(pageInfo.Name) + @""">");
					Response.Write(Resources.Messages.PostMessage);
					Response.Write("</a>");
				}
				Response.Write(@"<a id=""BackLink"" href=""");
				Response.Write(Tools.UrlEncode(pageInfo.Name));
				Response.Write(Settings.PageExtension);
				Response.Write(@"?NoRedirect=1"">");
				Response.Write(Resources.Messages.Back);
				Response.Write("</a>");
			}

			if(!discuss) {
				Response.Write(@"<a id=""HistoryLink"" href=""History.aspx?Page=");
				Response.Write(Tools.UrlEncode(pageInfo.Name));
				Response.Write(@""">");
				Response.Write(Resources.Messages.History);
				Response.Write("</a>");
			}
			Response.Write("</div>"); // EditHistoryLinkDiv

			StringBuilder prev = new StringBuilder(), next = new StringBuilder();
			if(Request["NavPath"] != null) {
				NavigationPath p = NavigationPaths.Instance.Find(Request["NavPath"]);
				int idx = p.Pages.IndexOf(pageInfo.Name);
				if(idx != -1) {
					if(idx > 0) {
						PageInfo prevPage = Pages.Instance.FindPage(p.Pages[idx - 1]);
						prev.Append(@"<a href=""Default.aspx?Page=");
						prev.Append(Tools.UrlEncode(prevPage.Name));
						prev.Append("&amp;NavPath=");
						prev.Append(Tools.UrlEncode(p.Name));
						prev.Append(@""" title=""");
						prev.Append(Resources.Messages.PrevPage);
						prev.Append(": ");
						prev.Append(Content.GetPageContent(prevPage, true).Title);
						prev.Append(@"""><b>&laquo;</b></a> ");
					}
					if(idx < p.Pages.Count - 1) {
						PageInfo nextPage = Pages.Instance.FindPage(p.Pages[idx + 1]);
						next.Append(@" <a href=""Default.aspx?Page=");
						next.Append(Tools.UrlEncode(nextPage.Name));
						next.Append("&amp;NavPath=");
						next.Append(Tools.UrlEncode(p.Name));
						next.Append(@""" title=""");
						next.Append(Resources.Messages.NextPage);
						next.Append(": ");
						next.Append(Content.GetPageContent(nextPage, true).Title);
						next.Append(@"""><b>&raquo;</b></a>");
					}
				}
			}
            Response.Write(@"<h1 class=""pagetitle"">");
			if(!code && !discuss) Response.Write(prev.ToString());
			if(discuss) {
				Response.Write(Resources.Messages.Discuss);
				Response.Write(": ");
			}
			Response.Write(c.Title);
			if(!code && !discuss) Response.Write(next.ToString());
			Response.Write("</h1>");

			if(!code && !discuss) {
				if(pageInfo.Status == PageStatus.Locked) {
					Response.Write(@"<div id=""PageLockedDiv"">");
					Response.Write(Resources.Messages.PageLocked);
					Response.Write("</div>");
				}
				if(pageInfo.Status == PageStatus.Public) {
					Response.Write(@"<div id=""PagePublicDiv"">");
					Response.Write(Resources.Messages.PagePublic);
					Response.Write("</div>");
				}

				Response.Write(@"<div id=""PrintLinkDiv""><a id=""PrintLink"" href=""Print.aspx?Page=");
				Response.Write(Tools.UrlEncode(pageInfo.Name));
				Response.Write(@""" target=""_blank"" title=""");
				Response.Write(Resources.Messages.PrinterFriendlyVersion);
				Response.Write(@""">");
				Response.Write(Resources.Messages.Print);
				Response.Write("</a></div>");

				Response.Write(@"<div id=""RssLinkDiv""><a id=""RssLink"" href=""RSS.aspx?Page=");
				Response.Write(Tools.UrlEncode(pageInfo.Name));
				Response.Write(@""" title=""");
				Response.Write(Resources.Messages.RssForThisPage);
				Response.Write(@""">RSS</a></div>");

				string shift = "";
				if(Request.Cookies[Settings.CultureCookieName] != null) shift = Request.Cookies[Settings.CultureCookieName]["T"];
				Response.Write(@"<div id=""PageInfoDiv"">");
				Response.Write(Resources.Messages.Modified);
				Response.Write(": ");
				Response.Write(string.Format("{0:" + Settings.DateTimeFormat + "}", Tools.AlignWithPreferences(c.LastModified, shift)));
				Response.Write(" ");
				Response.Write(Resources.Messages.By);
				Response.Write(" ");
				Response.Write(Users.Instance.UserLink(c.User));
				CategoryInfo[] cats = Pages.Instance.GetCategoriesPerPage(pageInfo);
				if(cats.Length > 0) {
					Response.Write(" - ");
					Response.Write(Resources.Messages.CategorizedAs);
					Response.Write(": ");
					for(int i = 0; i < cats.Length; i++) {
						Response.Write(@"<a href=""AllPages.aspx?Cat=");
						Response.Write(Tools.UrlEncode(cats[i].Name) + @""">");
						Response.Write(cats[i].Name);
						Response.Write("</a>");
						if(i != cats.Length - 1) Response.Write(", ");
					}
				}
				else {
					Response.Write(@" - <a href=""AllPages.aspx?Cat=-""><i>");
					Response.Write(Resources.Messages.Uncategorized);
					Response.Write("</i></a>");
				}
				string[] paths = NavigationPaths.Instance.PathsPerPage(pageInfo);
				if(paths.Length > 0) {
					Response.Write(" - ");
					Response.Write(Resources.Messages.Paths);
					Response.Write(": ");
					for(int i = 0; i < paths.Length; i++) {
						if(Request["NavPath"] != null && paths[i].ToLower(CultureInfo.CurrentCulture).Equals(Request["NavPath"].ToLower(CultureInfo.CurrentCulture))) Response.Write("<b>");
						Response.Write(@"<a href=""Default.aspx?Page=");
						Response.Write(Tools.UrlEncode(pageInfo.Name));
						Response.Write("&amp;NavPath=");
						Response.Write(Tools.UrlEncode(paths[i]));
						Response.Write(@""">");
						Response.Write(paths[i]);
						Response.Write("</a>");
						if(Request["NavPath"] != null && paths[i].ToLower(CultureInfo.CurrentCulture).Equals(Request["NavPath"].ToLower(CultureInfo.CurrentCulture))) Response.Write("</b>");
						if(i != paths.Length - 1) Response.Write(", ");
					}
				}
				Response.Write("</div>"); // PageInfodiv

				if(!Settings.DisableBreadcrumbsTrail) {
					Response.Write(@"<div id=""BreadcrumbsDiv"">");
					PageInfo[] bc = SessionFacade.Breadcrumbs.AllPages;
					int min = 3;
					if(bc.Length < 3) min = bc.Length;
					Response.Write(@"<div id=""BreadcrumbsDivMin"">");
					if(bc.Length > 3) {
						// Write button
						Response.Write(@"<a href=""#"" onclick=""javascript:return __ShowAllTrail();"" title=""");
						Response.Write(Resources.Messages.ViewBreadcrumbsTrail);
						Response.Write(@""">(");
						Response.Write(bc.Length.ToString());
						Response.Write(")</a> ");
					}
					for(int i = bc.Length - min; i < bc.Length; i++) {
						PageContent pc = Content.GetPageContent(bc[i], true);
						if(pc != null) {
							Response.Write("&raquo; ");
							if(bc[i] == pageInfo) Response.Write("<b>");
							Response.Write(@"<a href=""");
							Response.Write(Tools.UrlEncode(bc[i].Name));
							Response.Write(Settings.PageExtension);
							Response.Write(@""">");
							Response.Write(pc.Title);
							Response.Write("</a> ");
							if(bc[i] == pageInfo) Response.Write("</b>");
						}
					}
					Response.Write("</div>");
					Response.Write(@"<div id=""BreadcrumbsDivAll"" style=""display: none;"">");
					// Write button
					Response.Write(@"<a href=""#"" onclick=""javascript:return __HideTrail();"" title=""");
					Response.Write(Resources.Messages.HideBreadcrumbsTrail);
					Response.Write(@""">[X]</a> ");
					for(int i = 0; i < bc.Length; i++) {
						PageContent pc = Content.GetPageContent(bc[i], true);
						if(pc != null) {
							Response.Write("&raquo; ");
							if(bc[i] == pageInfo) Response.Write("<b>");
							Response.Write(@"<a href=""");
							Response.Write(Tools.UrlEncode(bc[i].Name));
							Response.Write(Settings.PageExtension);
							Response.Write(@""">");
							Response.Write(pc.Title);
							Response.Write("</a> ");
							if(bc[i] == pageInfo) Response.Write("</b>");
						}
					}
					Response.Write("</div>");
					Response.Write("</div>");
				}
				if(Request["From"] != null) {
					PageInfo source = Pages.Instance.FindPage(Request["From"]);
					if(source != null) {
						Response.Write(@"<div id=""RedirectionInfoDiv"">");
						Response.Write(Resources.Messages.RedirectedFrom);
						Response.Write(": ");
						Response.Write(@"<a href=""");
						Response.Write(Tools.UrlEncode(source.Name));
						Response.Write(Settings.PageExtension);
						Response.Write("?NoRedirect=1");
						Response.Write(@""">");
						PageContent w = Content.GetPageContent(source, true);
						Response.Write(w.Title);
						Response.Write("</a></div>");
					}
				}
			}
			if(discuss) {
				Response.Write(@"<div id=""PrintLinkDiv""><a id=""PrintLink"" href=""Print.aspx?Page=");
				Response.Write(Tools.UrlEncode(pageInfo.Name));
				Response.Write(@"&amp;Discuss=1"" target=""_blank"" title=""");
				Response.Write(Resources.Messages.PrinterFriendlyVersion);
				Response.Write(@""">");
				Response.Write(Resources.Messages.Print);
				Response.Write("</a></div>");

				Response.Write(@"<div id=""RssLinkDiv""><a id=""RssLink"" href=""RSS.aspx?Page=");
				Response.Write(Tools.UrlEncode(pageInfo.Name));
				Response.Write(@"&amp;Discuss=1"" title=""");
				Response.Write(Resources.Messages.RssForThisPage);
				Response.Write(@""">RSS</a></div>");

				Response.Write(@"<div id=""PageInfoDiv"">");
				PageContent cont = Content.GetPageContent(pageInfo, true);
				Response.Write(Resources.Messages.DiscussionFor);
				Response.Write(" <b>");
				Response.Write(cont.Title);
				Response.Write("</b>.");
				Response.Write("</div>");
			}
			Response.Write("</div>"); // PageHeaderDiv

			Response.Write(@"<div id=""PageContentDiv"">");
			if(!code && !discuss) {
				Response.Write(redirection);
				Response.Write(formattedContent);
				//Response.Write(Content.GetFormattedPageContent(pageInfo, true));
			}
			else {
				if(code) {
					Response.Write(@"<textarea style=""width: 98%; height: 500px;"" readonly=""true"">");
					Response.Write(Server.HtmlEncode(c.Content));
					//Response.Write(c.Content);
					Response.Write("</textarea>");
				}
				if(discuss) {
					PrintDiscussion();
				}
			}
			Response.Write("</div>");

			if(Settings.EnableDoubleClickEditing && !code && !discuss) {
				Response.Write(@"<script type=""text/javascript"">" + "\n");
				Response.Write("<!--\n");
				Response.Write("document.ondblclick = function() {\n");
				Response.Write("document.location = 'Edit.aspx?Page=");
				Response.Write(Tools.UrlEncode(pageInfo.Name));
				Response.Write("';\n");
				Response.Write("}\n");
				Response.Write("// -->\n");
				Response.Write("</script>");
			}

        }

		private void PrintViewCode() {
			Response.Write(@"<a id=""ViewCodeLink"" href=""");
			Response.Write(Tools.UrlEncode(pageInfo.Name));
			Response.Write(Settings.PageExtension);
			Response.Write(@"?Code=1"">");
			Response.Write(Resources.Messages.ViewPageCode);
			Response.Write("</a>");
		}

		private void PrintEditPage() {
			Response.Write(@"<a id=""EditLink"" href=""Edit.aspx?Page=");
			Response.Write(Tools.UrlEncode(pageInfo.Name));
			Response.Write(@""">");
			Response.Write(Resources.Messages.EditThisPage);
			Response.Write("</a>");
		}

		private void PrintDiscussion() {
			List<Message> messages = new List<Message>(Pages.Instance.GetPageMessages(pageInfo));
			if(messages.Count == 0) {
				Response.Write("<i>");
				Response.Write(Resources.Messages.NoMessages);
				Response.Write("</i>");
			}
			else PrintSubtree(messages, null);
		}

		/// <summary>
		/// Prints a subtree of Messages depth-first.
		/// </summary>
		/// <param name="messages">The Messages.</param>
		private void PrintSubtree(List<Message> messages, Message parent) {
			for(int i = 0; i < messages.Count; i++) {
				Response.Write(@"<div" + (parent != null ? @" class=""messagecontainer""" : @" class=""rootmessagecontainer""") + ">");
				PrintMessage(messages[i], parent);
				PrintSubtree(messages[i].Replies, messages[i]);
				Response.Write("</div>");
			}
		}

		private void PrintMessage(Message message, Message parent) {
			// Header
			Response.Write(@"<div class=""messageheader"">");
			if(!pageInfo.Provider.ReadOnly) {
				Response.Write(@"<div class=""reply""><a class=""reply"" href=""Post.aspx?Page=");
				Response.Write(Tools.UrlEncode(pageInfo.Name));
				Response.Write("&amp;Parent=");
				Response.Write(message.ID.ToString());
				Response.Write(@""">");
				Response.Write(Resources.Messages.Reply);
				Response.Write("</a>");
				if(SessionFacade.LoginKey != null && (message.Username.Equals(SessionFacade.Username) || SessionFacade.Admin)) {
					Response.Write(@" <a class=""edit"" href=""Post.aspx?Page=");
					Response.Write(Tools.UrlEncode(pageInfo.Name));
					Response.Write("&amp;Edit=");
					Response.Write(message.ID.ToString());
					Response.Write(@""">");
					Response.Write(Resources.Messages.Edit);
					Response.Write("</a>");
				}
				if(SessionFacade.LoginKey != null && SessionFacade.Admin) {
					Response.Write(@" <a class=""delete"" href=""Operation.aspx?Operation=DeleteMessage&amp;Message=");
					Response.Write(message.ID.ToString());
					Response.Write(@"&amp;Page=");
					Response.Write(Tools.UrlEncode(pageInfo.Name));
					Response.Write(@""">");
					Response.Write(Resources.Messages.Delete);
					Response.Write("</a>");
				}
				Response.Write("</div>");
			}
			string shift = "";
			if(Request.Cookies[Settings.CultureCookieName] != null) shift = Request.Cookies[Settings.CultureCookieName]["T"];
			Response.Write(Tools.AlignWithPreferences(message.DateTime, shift).ToString(Settings.DateTimeFormat));
			Response.Write(" ");
			Response.Write(Resources.Messages.By);
			Response.Write(" ");
			Response.Write(Users.Instance.UserLink(message.Username));

			// Subject
			if(message.Subject.Length > 0) {
				Response.Write(@"<br /><span class=""messagesubject"">");
				Response.Write(message.Subject);
				Response.Write("</span>");
			}

			Response.Write("</div>");

			// Body
			Response.Write(@"<div class=""messagebody"">");
			Response.Write(FormattingPipeline.FormatWithPhase3(FormattingPipeline.FormatWithPhase1And2(message.Body, null), null));
			Response.Write("</div>");
		}

	}

}
